package com.hjq.base.rollpager.rollpageradapter;

import android.database.DataSetObserver;
import android.view.View;
import android.view.ViewGroup;

import androidx.annotation.NonNull;
import androidx.viewpager.widget.PagerAdapter;

import com.hjq.base.rollpager.RollPagerView;
import com.hjq.base.rollpager.RollPagerView.HintViewDelegate;
import com.hjq.base.rollpager.RollPagerView.HintView;

import java.util.ArrayList;

/**
 * @author : create by  szh
 * @date : 2022/7/27 16:18
 * @desc :轮播适配器
 */

public abstract class LoopPagerAdapter extends PagerAdapter {

    private RollPagerView mViewPager;

    private ArrayList<View> mViewList = new ArrayList<>();

    private class LoopHintViewDelegate implements HintViewDelegate {
        @Override
        public void initView(int length, int gravity, HintView hintView) {
            if (hintView != null)
                hintView.initView(getRealCount(), gravity);
        }

        @Override
        public void setCurrentPosition(int position, HintView hintView) {
            int realCount = getRealCount();
            if (hintView != null)
                hintView.setCurrent(position % realCount);
        }
    }

    @Override
    public void notifyDataSetChanged() {
        super.notifyDataSetChanged();
        mViewList.clear();
    }

    @Override
    public void registerDataSetObserver(DataSetObserver observer) {
        super.registerDataSetObserver(observer);
        if (getCount() == 0) return;
        int half = Integer.MAX_VALUE / 2;
        int start = half - half % getRealCount();
        mViewPager.getViewPager().setCurrentItem(start, false);
    }

    public LoopPagerAdapter(RollPagerView viewPager) {
        this.mViewPager = viewPager;
        viewPager.setHintViewDelegate(new LoopHintViewDelegate());
    }

    /**
     * 获得viewpager中有多少个view
     */
    @Override
    public int getCount() {
        return getRealCount() <= 1 ? getRealCount() : Integer.MAX_VALUE;
    }

    public abstract int getRealCount();

    /**
     * ①将给定位置的view添加到ViewGroup(容器)中,创建并显示出来
     * ②返回一个代表新增页面的Object(key),通常都是直接返回view本身就可以了,
     * 当然你也可以 自定义自己的key,但是key和每个view要一一对应的关系
     */
    @NonNull
    @Override
    public Object instantiateItem(ViewGroup container, int position) {
        int realPosition = position % getRealCount();
        View itemView = findViewByPosition(container, realPosition);
        container.addView(itemView);
        return itemView;
    }

    private View findViewByPosition(ViewGroup container, int position) {
        for (View view : mViewList) {
            if (((int) view.getTag()) == position && view.getParent() == null) {
                return view;
            }
        }
        View view = getView(container, position);
        view.setTag(position);
        mViewList.add(view);
        return view;
    }

    public abstract View getView(ViewGroup container, int position);

    /**
     * 判断instantiateItem(ViewGroup, int)函数所返回来的Key与一个页面视图是否是
     * 代表的同一个视图(即它俩是否是对应的，对应的表示同一个View),
     * 通常我们直接写 return view == object
     */
    @Override
    public boolean isViewFromObject(View arg0, Object arg1) {
        return arg0 == arg1;
    }

    /**
     * 移除一个给定位置的页面。适配器有责任从容器中删除这个视图。
     * 这是为了确保在finishUpdate(viewGroup)返回时视图能够被移除。
     */
    @Override
    public void destroyItem(ViewGroup container, int position, Object object) {
        container.removeView((View) object);
    }
}
